﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AMM.Business.Config;
using AMM.CustomClassLibrary;
using AMM.CustomWinComponents.Validator;
using AMM.CustomWinControls;
using AMM.Model;
using AMM.Model.Config;
using AMM.UserControls;

namespace AMM.Forms.Config {
    public partial class FrmUser : FrmUserBase {

        private UserProcessor _userProcessor;
        private RoleProcessor _roleProcessor;
        private List<UserViewModel> _userList;
        private List<RoleViewModel> _roleList;
        private List<RoleViewModel> _ownRoleList;

        #region Override

        protected override string FunctionCode {
            get { return "AMM1101"; }
        }

        protected override BaseSearchControl SearchControl {
            get { return new UserSearchControl(); }
        }

        protected override void Button_Click(object sender, EventArgs e) {
            Button btn = sender as Button;
            switch (btn.Name) {
                case "btnAdd":
                    this.dgvRoles.GetSelectedRows<RoleViewModel>().ForEach(x => {
                        if (!this._ownRoleList.Contains(x)) {
                            this._ownRoleList.Add(x);
                        }
                    });
                    break;
                case "btnRemove":
                    this.dgvOwn.GetSelectedRows<RoleViewModel>().ForEach(x => {
                        this._ownRoleList.Remove(x);
                    });
                    break;
            }

            this.BindOwn();
        }

        protected override void Add() {
            this._ownRoleList.Clear();
            this.ResetForms();
            this.FBS.CurrentItem = new User() { IsEnabled = true, ClassStatus = ClassStatus.Added };

            this.btnAdd.Enabled = true;
            this.btnRemove.Enabled = true;
            this.gbUserInfo.Enabled = true;
            this.validator.ClearAllControlErrorIcons();
            base.Add();
        }

        protected override void Amend() {
            List<UserViewModel> selectedList = this.dgvUserList.GetSelectedRows<UserViewModel>();
            if (selectedList.Count > 1) { this.OnlySelectSingleRecord(); return; }
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            User user = this._userProcessor.FetchUserById(selectedList[0].Key);
            user.ClassStatus = ClassStatus.Updated;
            this.FBS.CurrentItem = user;
            this._ownRoleList = this._roleList.Where(x => user.UserRoles.Any(y => y.RoleId == x.Key)).ToList();
            this.BindOwn();
            this.btnAdd.Enabled = true;
            this.btnRemove.Enabled = true;
            this.gbUserInfo.Enabled = true;
            this.tbRePassword.Text = user.Password;
            base.Amend();
        }

        protected override void Save() {
            base.Save();
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                User user = this.FBS.CurrentItem;
                user.EmployeeId = 1;
                user.UserRoles.Clear();
                this.dgvOwn.Rows
                    .Cast<DataGridViewRow>()
                    .Select(x => Convert.ToInt32(x.Cells["Key"].Value))
                    .ToList().ForEach(x => {
                        user.UserRoles.Add(new UserRole() {
                            RoleId = x,
                            UserId = user.UserId
                        });
                    });

                if (user.ClassStatus == ClassStatus.Added) {
                    user.CreatedBy = LoginUserName;
                    this._userProcessor.Insert(user);
                }
                else {
                    user.ModifiedBy = LoginUserName;
                    this._userProcessor.Update(user);
                }

                this._userList = this._userProcessor.FetchUserViewModelList();
                this._ownRoleList.Clear();
                this.MDIParent.SetStatusInformation("保存成功");
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
            });
        }

        protected override void Delete() {
            base.Delete();
            List<UserViewModel> selectedList = this.dgvUserList.GetSelectedRows<UserViewModel>();
            if (selectedList.Count == 0) { this.ShouldSelectSingleRecord(); return; }
            if (selectedList.Any(x => x.IsSystem)) {
                this.ShowError("系统保留用户不能被删除");
                return;
            }
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                this._userProcessor.Delete(selectedList.Select(x => x.Key).ToArray());
                this._userList = this._userProcessor.FetchUserViewModelList();
                this._ownRoleList.Clear();
                this.MDIParent.SetStatusInformation("删除成功");
            }, () => {
                this.ResetForms();
                this.PreventCancel = false;
            });
        }

        protected override void Search(object sender, FrmSearch.SearchArgs e) {
            this.CreateNewThread(() => {
                if (e.IsRevert) {
                    this._userList = this._userProcessor.FetchUserViewModelList();
                }
                else {
                    UserSearchModel searchModel = (UserSearchModel)e.SearchModel;
                    this._userList = this._userList.Where(x => x.Name.Contains(searchModel.Name)).ToList();
                }
            }, () => {
                this.BindUserList();
            });
        }

        #endregion

        public FrmUser() {
            InitializeComponent();

            this.dgvUserList.DataGridViewModelType = typeof(UserViewModel);
            this.dgvOwn.DataGridViewModelType = typeof(RoleViewModel);
            this.dgvRoles.DataGridViewModelType = typeof(RoleViewModel);
        }

        #region Private methods

        private void ResetForms() {
            this.BindUserList();
            this.BindOwn();
            this.FBS.CurrentItem = null;
            this.tbRePassword.Text = string.Empty;
            this.btnAdd.Enabled = false;
            this.btnRemove.Enabled = false;
            this.gbUserInfo.Enabled = false;
        }

        private void CreateFormBindings() {
            this.FBS.CreateBinding(this.tbUserName, x => x.Text, y => y.Name);
            this.FBS.CreateBinding(this.tbPassword, x => x.Text, y => y.Password);
            this.FBS.CreateBinding(this.tbDescription, x => x.Text, y => y.Description);
            this.FBS.CreateBinding(this.cbIsEnabled, x => x.Checked, y => y.IsEnabled);
        }

        private void BindUserList() {
            this.dgvUserList.DataSource = new SortableBindingList<UserViewModel>(this._userList);
        }

        private void BindRoles() {
            this.dgvRoles.DataSource = new SortableBindingList<RoleViewModel>(this._roleList);
        }

        private void BindOwn() {
            this.dgvOwn.DataSource = new SortableBindingList<RoleViewModel>(this._ownRoleList);
        }

        private void BindValidation() {
            this.validator.SetType(this.tbUserName, ValidationType.Required);
            this.validator.SetRequiredMessage(this.tbUserName, this.RequiredMessage);

            this.validator.SetType(this.tbPassword, ValidationType.Required);
            this.validator.SetRequiredMessage(this.tbPassword, this.RequiredMessage);

            this.validator.SetType(this.tbRePassword, ValidationType.Required | ValidationType.Compare);
            this.validator.SetRequiredMessage(this.tbRePassword, this.RequiredMessage);
            this.validator.SetComparedControl(this.tbRePassword, this.tbPassword);
            this.validator.SetCompareMessage(this.tbRePassword, "两次输入的密码必须一致");
            this.validator.SetCompareOperator(this.tbRePassword, ValidationCompareOperator.Equal);
        }

        #endregion

        private void FrmUser_Load(object sender, EventArgs e) {
            this.CreateNewThread(() => {
                this.PreventCancel = true;
                this.FBS = new FlexBindingSource<User>();

                this._userProcessor = new UserProcessor();
                this._roleProcessor = new RoleProcessor();
                this._userList = this._userProcessor.FetchUserViewModelList();
                this._roleList = this._roleProcessor.FetchRoleViewModelList();
                this._ownRoleList = new List<RoleViewModel>();
            }, () => {
                this.WindowState = FormWindowState.Maximized;

                this.BindUserList();
                this.BindRoles();
                this.BindOwn();
                this.CreateFormBindings();
                this.BindValidation();
                this.PreventCancel = false;
            });
        }
    }
}
